﻿using huqiang.FileTool;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace huqiang.Communication
{
    public class KcpFileMission
    {
        public enum MissionState
        {
            None,
            RequestInfo,
            RequestDownload,
            Transmission,
            Done
        }
        public enum MissionMethod
        {
            Dowanload,
            HandleDownload,
            Upload,
            HandleUpload
        }
        public int ErrorCode;
        //public string name;
        public string url;
        public string realPath;
        public int CurrentPart
        {
            get
            {
                if (record == null)
                    return 0;
                return record.Position;
            }
        }
        public bool Compelete
        {
            get
            {
                if (record == null)
                    return false;
                return record.Compelete;
            }
        }
        public bool MoveNextPart()
        {
            if (record != null)
                return record.MoveNext();
            return false;
        }
        /// <summary>
        /// 总计分卷
        /// </summary>
        public int AllPart;
        public int RecvPart;
        public long FileID;
        public long Length;
        public long TransferCount;
        public long LastRecvTime;
        public long LastChangeTime;

        public string msg;
        MissionState _state;
        public MissionState State
        {
            get { return _state; }
            set
            {
                _state = value;
                LastChangeTime = DateTime.Now.Ticks;
            }
        }
        public MissionMethod method = MissionMethod.Dowanload;
        DownloadRecord record;
        FileStream write;
        FileStream read;
        public ShareFile shareFile;
        public void Open()
        {

        }
        /// <summary>
        /// 写入分卷记录
        /// </summary>
        /// <param name="part"></param>
        /// <returns></returns>
        public bool WriteRecord(int part)
        {
            if (record == null)
                return false;
            return record.WriteRecord(part);
        }
        public void WriteData(long position, byte[] dat, int offset, int len)
        {
            State = MissionState.Transmission;
            if (write != null)
            {
                RecvPart++;
                TransferCount += len;
                write.Seek(position, SeekOrigin.Begin);
                write.Write(dat, offset, len);
                if (TransferCount >= Length)
                {
                    State = MissionState.Done;
                    write.Dispose();
                    write = null;
                }
            }
        }
        public void ReadyDownload()
        {
            string p = realPath.Replace('\\', '/');
            int index = p.LastIndexOf('/');
            if (index > 0)
            {
                p = p.Substring(0, index);
                if (!Directory.Exists(p))
                    Directory.CreateDirectory(p);
            }
            State = MissionState.Transmission;
            if (File.Exists(realPath))
                File.Delete(realPath);
            write = File.Create(realPath);
            write.SetLength(Length);
            write.Flush();
            int kp = KcpFileTransfer.PartLength;
            int c = (int)(Length / kp);
            if (Length % kp > 0)
                c++;
            AllPart = c;
            record = new DownloadRecord();
            record.Reset(c);
        }
        public byte[] GetRecord()
        {
            if (record != null)
                return record.buf;
            return null;
        }
        public void SetRecord(byte[] dat)
        {
            if (record == null)
                record = new DownloadRecord();
            int kp = KcpFileTransfer.PartLength;
            int c = (int)(Length / kp);
            if (Length % kp > 0)
                c++;
            AllPart = c;
            record.Reset(c, dat);
        }
        public void Dispose()
        {
            if (read != null)
            {
                read.Dispose();
                read = null;
            }
            if (write != null)
            {
                write.Dispose();
                write = null;
            }
            //else
            //{
            //    KcpStreamManager.ReleaseStream(FileID);
            //}
            if (shareFile != null)
            {
                shareFile.Dispose();
                shareFile = null;
            }
        }
        static long ID;
        public void OpenUpload()
        {
            if (read != null)
                read.Dispose();
           
            ID++;
            FileID = ID;
            LastChangeTime = new FileInfo(realPath).LastWriteTime.Ticks;
            read = File.OpenRead(realPath);
            Length = read.Length;
        }
        public int ReadData(long position, byte[] buff, int offset, int len)
        {
            if (read != null)
            {
                read.Seek(position, SeekOrigin.Begin);
                return read.Read(buff, offset, len);
            }
            else if(shareFile!=null)
            {
                var share = shareFile.ShareStream;
                share.Seek(position, SeekOrigin.Begin);
                return share.Read(buff, offset, len);
            }
            return 0;
        }
    }
}
